// eee.Sheffield.PZ.Imaging
//
// Copyright ?Ping Zou, 2006
// sg71.cherub@gmail.com
using System;
using System.Collections.Generic;
using System.Text;
using eee.Sheffield.PZ.Math;
using System.Drawing;
using System.Drawing.Imaging;

namespace eee.Sheffield.PZ.Imaging.ImageFilter
{
    public class GaussianX : DoubleKernel1D // ImageFilter//, IGraylevelImageFilter
    {
        #region Fields
        /// <summary>
        /// standard deviation of the distribution
        /// </summary>
        private double _sigma;       
        /// <summary>
        /// convolution kernel
        /// </summary>
        //private double[] _kernel;
        /// <summary>
        /// kernel size (3 * mSigma)
        /// </summary>
        private int _kernelSize;
        /// <summary>
        /// kernel length (2 * mKernelSize + 1)
        /// </summary>
        private int _kernelLength;
        //private string _flag = "[Image -> Smooth -> GaussianX]";
        #endregion

        #region Properties
        public double Sigma { get { return _sigma; } set { _sigma = value; } }
        public double[] Kernel { get { return _kernel; } }
        #endregion

        #region constructor
        /// <summary>
        /// empty constructor
        /// </summary>
        public GaussianX() : this(0) { }
        /// <summary>
        /// imput standard deviation of the distribution
        /// </summary>
        /// <param name="sigma"></param>
        public GaussianX(double sigma)
        {
            _flag = "[Image -> Smooth -> GaussianX]";
            _sigma = sigma;
            _isXDirection = true;
            PrepareKernel();
        }
        #endregion

        #region prepare kernel
        public void PrepareKernel()
        {
            if (_sigma == 0)
                PZMath_errno.ERROR("GaussianX::PrepareKernel(), sigma is not prepared");
            _kernelSize = Convert.ToInt32(System.Math.Ceiling(3 * _sigma));
            _kernelLength = 2 * _kernelSize + 1;
            _kernel = new double[_kernelLength];
            // calculate kernel element
            double term1 = 1 / System.Math.Sqrt(2 * System.Math.PI) / _sigma;// / _sigma;
            for (int i = 0; i <= _kernelSize; i++)
            {
                double element = term1 * System.Math.Exp(-1.0 * (double)i * (double)i / 2.0 / _sigma / _sigma);
                _kernel[_kernelSize + i] = element;
                _kernel[_kernelSize - i] = element;
            }
        }
        #endregion

        #region Apply Filter        
        #endregion

    }
}
